package com.ibeeking.found.msg.rest.service.impl;

import cn.hutool.core.util.ObjectUtil;

import com.ibeeking.found.common.entity.DictDTO;
import com.ibeeking.found.common.enums.DictTypeEnum;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.utils.UserUtils;

import com.ibeeking.gmc.global.api.feign.GlobalDictFeignClient;
import com.ibeeking.found.msg.rest.service.ISmsTemplateService;
import com.ibeeking.found.msg.service.common.bo.SmsTemplateBO;

import com.ibeeking.found.msg.service.common.dos.SmsTemplateParamDO;
import com.ibeeking.found.msg.service.common.dos.SmsConfigSignDO;
import com.ibeeking.found.msg.service.common.dos.SmsTemplateDO;
import com.ibeeking.found.msg.service.common.param.SmsTemplateParam;
import com.ibeeking.found.msg.service.common.query.SmsTemplateQuery;

import com.ibeeking.found.msg.service.common.vo.SmsTemplateParamVO;
import com.ibeeking.found.msg.service.common.vo.SmsTemplateVO;
import com.ibeeking.found.msg.service.mapper.SmsConfigSignMapper;
import com.ibeeking.found.msg.service.mapper.SmsTemplateMapper;

import com.ibeeking.found.msg.service.mapper.SmsTemplateParamMapper;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;

import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.ibeeking.nematos.utils.result.ResponseResult;
import org.apache.commons.lang3.StringUtils;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName SmsTemplateServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2020-12-09 10:54
 **/
@Service
public class SmsTemplateServiceImpl extends ServiceImpl<SmsTemplateMapper, SmsTemplateDO> implements ISmsTemplateService {

    @Resource
    private SmsTemplateMapper smsTemplateMapper;

    @Resource
    private SmsTemplateParamMapper smsTemplateParamMapper;

    @Resource
    private SmsConfigSignMapper SmsConfigSignMapper;

    @Resource
    private GlobalDictFeignClient globalDictFeignClient;

    @Override
    public List<SmsTemplateVO> list(SmsTemplateQuery query) {
        List<SmsTemplateDO> smsTemplateDOS = smsTemplateMapper.selectList(new LambdaQueryWrapper<SmsTemplateDO>()
                .eq(query.getId() != null, SmsTemplateDO::getId, query.getId())
                .eq(query.getConfigId()!= null, SmsTemplateDO::getConfigId, query.getConfigId())
                .eq(query.getSignId()!= null, SmsTemplateDO::getSignId, query.getSignId())
                .eq(query.getTemplateType()!= null, SmsTemplateDO::getTemplateType, query.getTemplateType())
                .eq(StringUtils.isNotBlank(query.getTemplateCode()), SmsTemplateDO::getTemplateCode, query.getTemplateCode())
                .eq(StringUtils.isNotBlank(query.getTemplateName()), SmsTemplateDO::getTemplateName, query.getTemplateName())
                .eq(StringUtils.isNotBlank(query.getSmsVendorCode()), SmsTemplateDO::getSmsVendorCode, query.getSmsVendorCode())
                .eq(query.getPublishStatus() != null, SmsTemplateDO::getPublishStatus, query.getPublishStatus())
                .orderByDesc(SmsTemplateDO::getModifyTime)
        );


        List<SmsTemplateVO> smsTemplateVOS = JsonUtils.jsonToList(smsTemplateDOS, SmsTemplateVO.class);
        List<SmsTemplateVO> smsTemplateResultVOS = new ArrayList<>();
        if(Collections3.isNotEmpty(smsTemplateVOS)) {
            Map<String, String> smsVendorMap = getSmsVendorDictNames();
            Map<String, String> smsTemplateTypeMap = getSmsTemplateTypeDictNames();
            Map<Long, String> smsConfigSignMap = getSmsConfigSignNames();
            smsTemplateResultVOS = smsTemplateVOS.stream().map(d -> {
                SmsTemplateVO smsTemplateVO = BeanUtil.convertBean(d, SmsTemplateVO.class);
                smsTemplateVO.setSmsVendorName(smsVendorMap.get(d.getSmsVendorCode()));
                smsTemplateVO.setTemplateTypeDesc(smsTemplateTypeMap.get(d.getTemplateType().toString()));
                smsTemplateVO.setSignName(smsConfigSignMap.get(d.getSignId()));
                smsTemplateVO.setPublishStatusDesc(PublishStatusEnum.getName(d.getPublishStatus()));
                return smsTemplateVO;
            }).collect(Collectors.toList());
        }

        return smsTemplateResultVOS;
    }

    @Override
    public List<SmsTemplateVO> listByConfigId(Long configId) {
        SmsTemplateQuery query = new SmsTemplateQuery();
        query.setConfigId(configId);
        return getBean().list(query);
    }

    @Override
    public List<SmsTemplateVO> listEffectTemplateByDefaultConfig(){
        List<SmsTemplateDO> smsTemplateDOS = smsTemplateMapper.listEffectTemplateByDefaultConfig();
        List<SmsTemplateVO> smsTemplateVOS = JsonUtils.jsonToList(smsTemplateDOS, SmsTemplateVO.class);
        List<SmsTemplateVO> smsTemplateResultVOS = new ArrayList<>();
        if(Collections3.isNotEmpty(smsTemplateVOS)) {
            Map<String, String> smsVendorMap = getSmsVendorDictNames();
            Map<String, String> smsTemplateTypeMap = getSmsTemplateTypeDictNames();
            Map<Long, String> smsConfigSignMap = getSmsConfigSignNames();
            smsTemplateResultVOS = smsTemplateVOS.stream().map(d -> {
                SmsTemplateVO smsTemplateVO = BeanUtil.convertBean(d, SmsTemplateVO.class);
                smsTemplateVO.setSmsVendorName(smsVendorMap.get(d.getSmsVendorCode()));
                smsTemplateVO.setTemplateTypeDesc(smsTemplateTypeMap.get(d.getTemplateType().toString()));
                smsTemplateVO.setSignName(smsConfigSignMap.get(d.getSignId()));
                smsTemplateVO.setPublishStatusDesc(PublishStatusEnum.getName(d.getPublishStatus()));
                return smsTemplateVO;
            }).collect(Collectors.toList());
        }

        return smsTemplateResultVOS;
    }
    /**
     * 邮件参数列表
     *
     * @param
     * @return
     */
    @Override
    public List<SmsTemplateParamVO> listSmsTemplateParam(Long templateId) {
        List<SmsTemplateParamDO> smsTemplateParamDOS = smsTemplateParamMapper.selectList(new LambdaQueryWrapper<SmsTemplateParamDO>()
                .eq(SmsTemplateParamDO::getTemplateId, templateId)
        );
        List<SmsTemplateParamVO> smsTemplateParamVOS = JsonUtils.jsonToList(smsTemplateParamDOS, SmsTemplateParamVO.class);
        return smsTemplateParamVOS;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(SmsTemplateParam smsTemplateParam) {

        Long userId = UserUtils.getUserId();

        Long id1 = getBean().checkName(smsTemplateParam.getConfigId(), smsTemplateParam.getTemplateName());
        if (null != id1 && id1.equals(smsTemplateParam.getId())) {
            throw new BusinessException("当前模板名称已存在");
        }
        Long id2 = getBean().checkCode(smsTemplateParam.getConfigId(), smsTemplateParam.getTemplateCode());
        if (null != id2 && id2.equals(smsTemplateParam.getId())) {
            throw new BusinessException("当前模板编码已存在");
        }

        SmsTemplateDO smsTemplateDO = BeanUtil.convertBean(smsTemplateParam, SmsTemplateDO.class);
        smsTemplateDO.setCreateBy(userId);
        smsTemplateDO.setCreateTime(LocalDateTime.now());
        smsTemplateDO.setModifyTime(LocalDateTime.now());
        return smsTemplateMapper.insert(smsTemplateDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean modify(SmsTemplateParam smsTemplateParam) {

        Long userId = UserUtils.getUserId();

        SmsTemplateDO smsTemplateDO = BeanUtil.convertBean(smsTemplateParam, SmsTemplateDO.class);
        smsTemplateDO.setModifyBy(userId);
        smsTemplateDO.setModifyTime(LocalDateTime.now());
        return smsTemplateMapper.updateById(smsTemplateDO) > 0;
    }

    @Override
    public SmsTemplateVO view(Long id) {
        SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectById(id);
        if(smsTemplateDO == null){
            throw new BusinessException("数据不存在");
        }

        SmsTemplateVO smsTemplateVO = BeanUtil.convertBean(getBean().queryById(id), SmsTemplateVO.class);
        if(smsTemplateVO != null){
            Map<String, String> smsVendorMap = getSmsVendorDictNames();
            Map<String, String> smsTemplateTypeMap = getSmsTemplateTypeDictNames();
            Map<Long, String> smsConfigSignMap = getSmsConfigSignNames();
            smsTemplateVO.setSmsVendorName(smsVendorMap.get(smsTemplateVO.getSmsVendorCode()));
            smsTemplateVO.setTemplateTypeDesc(smsTemplateTypeMap.get(smsTemplateVO.getTemplateType().toString()));
            smsTemplateVO.setSignName(smsConfigSignMap.get(smsTemplateVO.getSignId()));
            smsTemplateVO.setPublishStatusDesc(PublishStatusEnum.getName(smsTemplateVO.getPublishStatus()));
        }

        return smsTemplateVO;
    }

    @Override
    public SmsTemplateVO queryTemplateByCode(String code) {
        SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(new LambdaQueryWrapper<SmsTemplateDO>()
                .eq(SmsTemplateDO::getTemplateCode, code));
        if(ObjectUtil.isNull(smsTemplateDO))throw new BusinessException("根据code查询短信模板配置失败 配置不存在 code:" + code);
        SmsTemplateVO smsTemplateVO = BeanUtil.convertBean(smsTemplateDO, SmsTemplateVO.class);
        if(smsTemplateVO != null){
            Map<String, String> smsVendorMap = getSmsVendorDictNames();
            Map<String, String> smsTemplateTypeMap = getSmsTemplateTypeDictNames();
            Map<Long, String> smsConfigSignMap = getSmsConfigSignNames();
            smsTemplateVO.setSmsVendorName(smsVendorMap.get(smsTemplateVO.getSmsVendorCode()));
            smsTemplateVO.setTemplateTypeDesc(smsTemplateTypeMap.get(smsTemplateVO.getTemplateType().toString()));
            smsTemplateVO.setSignName(smsConfigSignMap.get(smsTemplateVO.getSignId()));
            smsTemplateVO.setPublishStatusDesc(PublishStatusEnum.getName(smsTemplateVO.getPublishStatus()));
        }
        return smsTemplateVO;
    }

    @Override
    public SmsTemplateBO queryById(Long id) {
        SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectById(id);
        if(ObjectUtil.isNull(smsTemplateDO))throw new BusinessException("查询短信模板配置不存在");
        return BeanUtil.convertBean(smsTemplateDO, SmsTemplateBO.class);
    }

    /**
     * 根据code查询短信模板配置
     *
     * @param code
     * @return
     */
    @Override
    public SmsTemplateBO querySmsTemplateBOByCode(String code) {
        SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(new LambdaQueryWrapper<SmsTemplateDO>()
                .eq(SmsTemplateDO::getTemplateCode, code));
        if(ObjectUtil.isNull(smsTemplateDO))throw new BusinessException("根据code查询短信模板配置失败 配置不存在 code:" + code);
        return BeanUtil.convertBean(smsTemplateDO, SmsTemplateBO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean changeStatus(Long id, Integer status) {
        Long userId = UserUtils.getUserId();
        SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectById(id);
        if(ObjectUtil.isNull(smsTemplateDO))throw new BusinessException("查询短信模板配置不存在");

        smsTemplateDO.setModifyBy(userId);
        smsTemplateDO.setModifyTime(LocalDateTime.now());
        smsTemplateDO.setPublishStatus(status);
        return smsTemplateMapper.updateById(smsTemplateDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean del(Long id) {
        SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectById(id);
        if(ObjectUtil.isNull(smsTemplateDO))throw new BusinessException("查询短信模板配置不存在");

        return smsTemplateMapper.deleteById(id) > 0;
    }

    @Override
    public Long checkName(Long configId, String name) {
        SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(new LambdaQueryWrapper<>(SmsTemplateDO.class)
                .eq(SmsTemplateDO::getConfigId, configId).eq(SmsTemplateDO::getTemplateName, name));
        if (null == smsTemplateDO) {
            throw new BusinessException("模板名称已存在");
        }
        return smsTemplateDO.getId();
    }

    @Override
    public Long checkCode(Long configId, String code) {
        SmsTemplateDO smsTemplateDO = smsTemplateMapper.selectOne(new LambdaQueryWrapper<>(SmsTemplateDO.class)
                .eq(SmsTemplateDO::getConfigId, configId).eq(SmsTemplateDO::getTemplateCode, code));
        if (null == smsTemplateDO) {
            throw new BusinessException("模板代码已存在");
        }
        return smsTemplateDO.getId();
    }

    private SmsTemplateServiceImpl getBean() {
        return SpringBeanUtil.getBean(SmsTemplateServiceImpl.class);
    }

    private Map<String, String> getSmsVendorDictNames() {
        ResponseResult<List<DictDTO>> responseResult =  globalDictFeignClient.queryDictByType(DictTypeEnum.MSG_SMS_VENDOR.getValue());
        if (responseResult == null) return Collections3.emptyMap();
        List<DictDTO> dictDTOS =  responseResult.getData();
        if (Collections3.isEmpty(dictDTOS)) return Collections3.emptyMap();
        Map<String, String> dictDTOSMaps =   dictDTOS.stream().collect(Collectors.toMap(DictDTO::getValue, DictDTO::getLabel, (key1, key2) -> key2));

        return dictDTOSMaps;
    }

    private Map<String, String> getSmsTemplateTypeDictNames() {
        ResponseResult<List<DictDTO>> responseResult =  globalDictFeignClient.queryDictByType(DictTypeEnum.MSG_TEMPLATE_TYPE.getValue());
        if (responseResult == null) return Collections3.emptyMap();
        List<DictDTO> dictDTOS =  responseResult.getData();
        if (Collections3.isEmpty(dictDTOS)) return Collections3.emptyMap();
        Map<String, String> dictDTOSMaps =   dictDTOS.stream().collect(Collectors.toMap(DictDTO::getValue, DictDTO::getLabel, (key1, key2) -> key2));

        return dictDTOSMaps;
    }

    private Map<Long, String> getSmsConfigSignNames() {
        List<SmsConfigSignDO> smsConfigSignDOS = SmsConfigSignMapper.selectList(new LambdaQueryWrapper<SmsConfigSignDO>());
        if (Collections3.isEmpty(smsConfigSignDOS)) return Collections3.emptyMap();
        Map<Long, String> smsConfigSignMaps =   smsConfigSignDOS.stream().collect(Collectors.toMap(SmsConfigSignDO::getId, SmsConfigSignDO::getSignName, (key1, key2) -> key2));

        return smsConfigSignMaps;
    }

}
